/*
+--------------------------------------------------------------------------
o|   Mblog [#RELEASE_VERSION#]
|   ========================================
|   Copyright (c) 2014, 2015 mtons. All Rights Reserved
|   http://www.mtons.com
|
+---------------------------------------------------------------------------
*/
package com.hefei.blog.admin.persist.service.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.hefei.blog.admin.data.Admin;
import com.hefei.blog.admin.data.AdminProfile;
import com.hefei.blog.admin.data.AuthMenu;
import com.hefei.blog.admin.persist.dao.AdminDao;
import com.hefei.blog.admin.persist.dao.RoleDao;
import com.hefei.blog.admin.persist.entity.AdminPO;
import com.hefei.blog.admin.persist.entity.AuthMenuPO;
import com.hefei.blog.admin.persist.entity.RolePO;
import com.hefei.blog.admin.persist.service.AdminService;
import com.hefei.blog.admin.persist.utils.BeanMapUtils;
import com.hefei.blog.base.cache.AdminEhcacheManager;
import com.hefei.blog.base.paging.Paging;
import com.hefei.common.returncode.ReturnCode;
import com.hefei.common.util.encrypt.MD5;
import com.hefei.common.util.encrypt.MD5Version;
import com.hefei.frontend.framework.base.CookieConstants;
import com.hefei.frontend.framework.base.UserCookieUtil;
import com.hefei.frontend.framework.base.user.UserCookie;
import com.hefei.frontend.framework.cookie.util.CookieUtil;
import com.hefei.frontend.framework.http.request.RequestThreadLocal;

@Service
public class AdminServiceImpl implements AdminService {
	
	private Logger logger = Logger.getLogger(AdminServiceImpl.class);
	@Autowired
	private AdminDao adminDao;
	@Autowired
	private RoleDao roleDao;
	
	@Override
	@Transactional
	public String login(String loginName,String password,HttpServletRequest request,HttpServletResponse response) {
		String returnCode = ReturnCode.RETURN_CODE_ERROR;
		try {
			AdminProfile profile = login(loginName, MD5.MD5Encrypt(password,MD5Version.V1.getVersion()));
			if(profile!=null){
				writeLoginCookie(profile, request, response);
				AdminEhcacheManager.putAdminProfile(profile);
				
				returnCode = ReturnCode.RETURN_CODE_SUCCESS;
			}
		} catch (Exception e) {
			logger.error("error:",e);
		}
		return returnCode;
	}

	
	public void writeLoginCookie(AdminProfile profile, HttpServletRequest request,HttpServletResponse response) throws Exception{
		try {
			UserCookie userCookie = new UserCookie();
			userCookie.setUserId(profile.getId());
			userCookie.setAvatarPath(profile.getAvatar());
			userCookie.setNickname(profile.getName());
			
			UserCookieUtil.setUserCookie(request, response, CookieConstants.COOKIE_DOMAIN, CookieConstants.COOKIE_NAME_WEB, userCookie, CookieConstants.COOKIE_AGE_SESSION, true, false);
			CookieUtil.setCookie(request, response, CookieConstants.COOKIE_DOMAIN, CookieConstants.COOKIE_NAME_USER_LOGIN_USERID, userCookie.getUserId().toString(), CookieConstants.COOKIE_AGE_SESSION, true, false);
		
			CookieUtil.setCookie(request, response, CookieConstants.COOKIE_DOMAIN, CookieConstants.COOKIE_NAME_USER_LOGIN_NICKNAME, userCookie.getNickname(), CookieConstants.COOKIE_AGE_ONE_WEEK, true, false);
			
		} catch (Exception e) {
			logger.error(RequestThreadLocal.getRequestStr()+"error:",e);
			throw e;
		}
	}
	
	@Override
	@Transactional
	public AdminProfile login(String username, String password) {
		AdminPO po = adminDao.getByUsername(username);
		
		AdminProfile u = null;

		Assert.notNull(po, "账户不存在");

//		Assert.state(po.getStatus() != Const.STATUS_CLOSED, "您的账户已被封禁");
		logger.info("======= " + po.getPassword()+"======= " +  password);
		if (StringUtils.equals(po.getPassword(), password)) {
			po.setLastLogin(Calendar.getInstance().getTime());
			u = BeanMapUtils.copyPassport(po);
		}
		return u;
	}

	@Transactional(readOnly = true)
	public AdminProfile getProfile(Long userId){
		AdminProfile u = null;
		u = AdminEhcacheManager.getAdminProfile(userId);
		if( u == null){
			AdminPO po = adminDao.get(userId);

			Assert.notNull(po, "账户不存在");

//			Assert.state(po.getStatus() != Const.STATUS_CLOSED, "您的账户已被封禁");

			u = BeanMapUtils.copyPassport(po);

			AdminEhcacheManager.putAdminProfile(u);
		}
		return u;
	}
	
	@Transactional(readOnly = true)
	public AdminProfile getProfileByName(String username) {
		AdminPO po = adminDao.getByUsername(username);
		AdminProfile u = null;

		Assert.notNull(po, "账户不存在");

//		Assert.state(po.getStatus() != Const.STATUS_CLOSED, "您的账户已被封禁");
		po.setLastLogin(Calendar.getInstance().getTime());

		u = BeanMapUtils.copyPassport(po);

		AdminEhcacheManager.putAdminProfile(u);
		return u;
	}


	@Override
	@Transactional(readOnly = true)
	public Admin get(long userId) {
		AdminPO po = adminDao.get(userId);
		Admin ret = null;
		if (po != null) {
			ret = BeanMapUtils.copy(po, 0);
		}
		return ret;
	}
	
	@Override
	@Transactional(readOnly = true)
	public Admin getByUsername(String username) {
		AdminPO po = adminDao.getByUsername(username);
		Admin ret = null;
		if (po != null) {
			ret = BeanMapUtils.copy(po, 1);
		}
		return ret;
	}
//

	@Override
	@Transactional
	public void updateRole(long id, Long[] roleIds) {
		List<RolePO> rolePOs = new ArrayList<RolePO>();
		for(Long roleId:roleIds){
			RolePO rolePO = roleDao.get(roleId);
			rolePOs.add(rolePO);
		}
		AdminPO po = adminDao.get(id);

		if (po != null) {
			po.setRoles(rolePOs);
			adminDao.update(po);
		}
		
		AdminProfile profile = BeanMapUtils.copyPassport(po);
		AdminEhcacheManager.putAdminProfile(profile);
	}

	@Override
	@Transactional(readOnly = true)
	public void paging(Paging paging, String key) {
		List<AdminPO> list = adminDao.paging(paging, key);
		//TODO 不知道为啥，当一个用户有多角色时，查询出来的用户会显示重复的，下面这段去掉重复
//		Set<AdminPO> userSet = new HashSet<AdminPO>();
//		for(int i=0;i<list.size();i++){
//			userSet.add(list.get(i));
////			for(int j=i+1;j<list.size();j++){
////				if(list.get(i).equals(list.get(j))){
////					list.remove(i);
////				}
////			}
//		}
//		list.clear();
//		for(AdminPO AdminPO : userSet){
//			list.add(AdminPO);
//		}
		List<Admin> rets = new ArrayList<>();

		for (AdminPO po : list) {
			Admin u = BeanMapUtils.copy(po , 1);
			rets.add(u);
		}
		paging.setResults(rets);
	}

	@Override
	@Transactional(readOnly = true)
	public Map<Long, Admin> findMapByIds(Set<Long> ids) {
		if (ids == null || ids.isEmpty()) {
			return Collections.emptyMap();
		}
		List<AdminPO> list = adminDao.findByIds(ids);
		Map<Long, Admin> ret = new HashMap<>();

		list.forEach(po -> {
			ret.put(po.getId(), BeanMapUtils.copy(po, 0));
		});
		return ret;
	}

	@Override
	@Transactional(readOnly = true)
	public List<AuthMenu> getMenuList(long id) {
		List<AuthMenu> menus = new ArrayList<AuthMenu>();
		AdminPO adminPO = adminDao.get(id);
		List<RolePO> roles = adminPO.getRoles();
		for(RolePO role : roles){
			List<AuthMenuPO> menuPOs = role.getAuthMenus();
			for(AuthMenuPO menuPO : menuPOs){
				AuthMenu menu = BeanMapUtils.copy(menuPO);
				if(!menus.contains(menu)){
					menus.add(menu);
				}
			}
		}
		return menus;
	}


}
